
-- $Id: Core.lua 73 2009-04-06 14:21:13Z Fylgjas $

-- ========================================================================= --
-- Copyright © 2009 Thomas ROBERT (aka Fylgjas EU - Marécage de Zangar)      --
-- ========================================================================= --
-- This file is part of FyLooter.                                            --
--                                                                           --
-- FyLooter is free software: you can redistribute it and/or modify it under --
-- the terms of the GNU General Public License as published by the Free      --
-- Software Foundation, either version 3 of the License, or (at your option) --
-- any later version.                                                        --
--                                                                           --
-- FyLooter is distributed in the hope that it will be useful, but WITHOUT   --
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     --
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for  --
-- more details.                                                             --
--                                                                           --
-- You should have received a copy of the GNU General Public License along   --
-- with FyLooter. If not, see <http://www.gnu.org/licenses/>.                --
-- ========================================================================= --

local revision = tonumber(string.sub("$Rev: 73 $", 7, -3));

if (FyLooter.revision < revision) then
  FyLooter.revision = revision;
end

-- ========================================================================= --

function FyLooter:OnMasterLootListOpened()
  FyLooter:Delete(FyLooter.loot);
  FyLooter.loot = {};

  FyLooter.loot.slot = LootFrame.selectedSlot;
  FyLooter.loot.item = GetLootSlotLink(loot.slot);
  FyLooter.loot.ml = UnitName("player");

  local quality = select(3, GetItemInfo(loot.item));
  local threshold = GetLootThreshold();
  if (not threshold) then
    threshold = 4;
  end
  if (quality < threshold) then return end

--  FyLooter.MinimapButton:Disable();

  FyLooter:Delete(FyLooter.candidates);
  FyLooter.candidates = {};

  for i = 1, 40 do
    local candidate = GetMasterLootCandidate(i);

    if (candidate) then
      local playerIdx, characterIdx = FyLooter.CharactersModel:GetCharacterIdx(candidate);

      if (playerIdx and characterIdx) then    -- TODO find an other issue
        FyLooter.candidates[i] = {
          ["name"] = candidate,
          ["status"] = nil,
        };
      else
        DEFAULT_CHAT_FRAME:AddMessage(format("FyLooter: WARNING %s isn't listed.", candidate), 1, 0, 0);
      end
    end
  end

  FyLooter:RequestBid();
end

-- ========================================================================= --

-- 
-- FyLooter:Commit()
--
function FyLooter:Commit(target)
  if (target) then
    local sdata = self:Serialize("COMMIT", {
      ["timestamp"] = self.db.timestamp,
      ["players"] = self.db.players,
    });

    self:SendCommMessage("FyLooter_Comm", sdata, "WHISPER", target);
  elseif (self.pending) then
    self.db.timestamp = time();
 
    local sdata = self:Serialize("COMMIT", {
      ["timestamp"] = self.db.timestamp,
      ["players"] = self.db.players,
    });

    self:SendCommMessage("FyLooter_Comm", sdata, "GUILD");

    if (GetNumRaidMembers() > 0) then
      self:SendCommMessage("FyLooter_Comm", sdata, "RAID");
    end

    self.pending = false;
  end
end

-- 
-- FyLooter:Checkout()
--
function FyLooter:Checkout()
  local sdata = self:Serialize("CHECKOUT", {
    ["timestamp"] = self.db.timestamp,
    ["players"] = self.db.players,
  });

  self:SendCommMessage("FyLooter_Comm", sdata, "GUILD");

  if (GetNumRaidMembers() > 0) then
    self:SendCommMessage("FyLooter_Comm", sdata, "RAID");
  end
end

-- 
-- FyLooter:RequestBid()
-- 
function FyLooter:RequestBid()
  local sdata = self:Serialize("BID_REQUEST", {
    ["loot"] = self.loot,
    ["candidates"] = self.candidates,
  });

  for i = 1, #self.candidates do
    self:SendCommMessage("FyLooter_Comm", sdata, "WHISPER", self.candidates[i]);
  end
end

-- 
-- FyLooter:AnswerBid()
--
function FyLooter:AnswerBid(status)
  local sdata = self:Serialize("BID_ANSWER", {
    ["loot"] = self.loot,
    ["status"] = status,
  });

  self:SendCommMessage("FyLooter_Comm", sdata, "RAID");
end

-- 
-- FyLooter:CheckVersion()
--
function FyLooter:CheckVersion()
  local sdata = self:Serialize("REVISION_REQUEST", {
      ["revision"] = FyLooter.revision,
  });

  self:SendCommMessage("FyLooter_Comm", sdata, "GUILD");

  if (GetNumRaidMembers() > 0) then
    self:SendCommMessage("FyLooter_Comm", sdata, "RAID");
  end
end

-- 
-- FyLooter:PrintVersions()
--
function FyLooter:PrintVersions()
  table.sort(self.versions);

  for name, revision in pairs(self.versions) do
    local color = "FFFFFF";
    if (revision > self.revision) then
      color = "00FF00";
    elseif (revision < self.revision) then
      color = "FF0000";
    end
    DEFAULT_CHAT_FRAME:AddMessage(format("%-12s r|cFF%s%d|r", name, color, revision), 0.2, 0.5, 0.8);
  end
end

-- ========================================================================= --

-- 
-- FyLooter:OnComm
--
function FyLooter:OnComm(sdata, channel, sender)
  local ok, event, data = FyLooter:Deserialize(sdata);

  if (not ok) then
    DEFAULT_CHAT_FRAME:AddMessage("FyLooter: " .. event, 1, 0, 0);
    return;
  end

  -- ON_COMMIT
  if (event == "COMMIT") then                                                  FyLooter:Debug("ON_COMMIT");
    if (data.timestamp > FyLooter.db.timestamp) then
      FyLooter:Delete(FyLooter.db.players);
      FyLooter.db.players = data.players;
      FyLooter.db.timestamp = data.timestamp;
      
      FyLooter.CharactersModel:Update();

      DEFAULT_CHAT_FRAME:AddMessage(format("FyLooter: Player list updated from %s.", sender), 0.2, 0.5, 0.8);
    end

  -- ON_CHECKOUT
  elseif (event == "CHECKOUT") then                                            FyLooter:Debug("ON_CHECKOUT");
    if (sender == UnitName("player")) then return end
    
    if (data.timestamp < FyLooter.db.timestamp) then
      FyLooter:Commit(sender);
    elseif (data.timestamp > FyLooter.db.timestamp) then
      FyLooter:Delete(FyLooter.db.players);
      FyLooter.db.players = data.players;
      FyLooter.db.timestamp = data.timestamp;
      
      FyLooter.CharactersModel:Update();

      DEFAULT_CHAT_FRAME:AddMessage(format("FyLooter: Player list updated from %s.", sender), 0.2, 0.5, 0.8);
    end

  -- ON_BID_REQUEST
  elseif (event == "BID_REQUEST") then                                         FyLooter:Debug("ON_BID_REQUEST");
    FyLooter:Close();

    FyLooter:Delete(FyLooter.candidates);
    FyLooter.candidates = data.candidates;
    FyLooter.loot = data.loot;

    FyLooter.ScrollFrame:SetModel(FyLooter.CandidatesModel);
    FyLooter.LootFrame:SetItem(data.loot.item);

    FyLooter.TitleFrame:Show();
    FyLooter.LootFrame:Show();
    FyLooter.BidFrame:Show();

    FyLooter.Anchor:SetHeight(FyLooter.TitleFrame:GetHeight() + FyLooter.LootFrame:GetHeight() + FyLooter.BidFrame:GetHeight());
    FyLooter.Anchor:Show();
    
  -- ON_BID_ANSWER
  elseif (event == "BID_ANSWER") then                                          FyLooter:Debug("ON_BID_ANSWER");
    if (data.loot.item == FyLooter.loot.item) then
      FyLooter.CandidatesModel:SetStatus(sender, data.status);
    end
    
  -- ON_LOOT_CLEARED
  elseif (event == "LOOT_CLEARED") then                                        FyLooter:Debug("ON_LOOT_CLEARED");
    if (data.loot.item == FyLooter.loot.item) then
      FyLooter:Delete(FyLooter.candidates);

      FyLooter.CandidatesModel:SetSelection(nil);

      FyLooter.MasterFrame.FreeButton:Disable();
      FyLooter.MasterFrame.PayButton:Disable();

      FyLooter:Close();
    end
    
  -- ON_REVISION_REQUEST
  elseif (event == "REVISION_REQUEST") then                                    FyLooter:Debug("ON_REVISION_REQUEST");
    if (data.revision > FyLooter.revision) then
      if (not FyLooter.deprecated) then
        FyLooter.deprecated = true;

        DEFAULT_CHAT_FRAME:AddMessage("|cFF8033CC FyLooter:|r A new version is available! Please visit |cFF80CC33http://code.google.com/p/fylooter/|r.", 0.8, 0.2, 0.5);
      end
    else
      local sdata = FyLooter:Serialize("REVISION_ANSWER", {
        ["revision"] = FyLooter.revision,
      });

      FyLooter:SendCommMessage("FyLooter_Comm", sdata, "WHISPER", sender);
    end
    
  -- ON_REVISION_ANSWER
  elseif (event == "REVISION_ANSWER") then                                     FyLooter:Debug("ON_REVISION_ANSWER");
    FyLooter.versions[sender] = data.revision;

    if ((not FyLooter.deprecated) and (data.revision > FyLooter.revision)) then
      FyLooter.deprecated = true;

      DEFAULT_CHAT_FRAME:AddMessage("|cFF8033CC FyLooter:|r A new version is available! Please visit |cFF80CC33http://code.google.com/p/fylooter/|r.", 0.8, 0.2, 0.5);
    end

  -- ON_??
  else                                                                         FyLooter:Debug("ON_??");
    -- TODO
  end
end

-- ========================================================================= --

